package cc.rengu.igas.opms.core.service.trans.common;

import cc.rengu.igas.opms.common.constant.OpmsParamConstant;
import cc.rengu.igas.opms.common.enums.RespCodeEnum;
import cc.rengu.igas.opms.core.service.base.ManageService;
import cc.rengu.igas.opms.facade.bean.BizProdInfo;
import cc.rengu.igas.opms.facade.request.OnlineCasherInfoRequest;
import cc.rengu.igas.opms.facade.response.OnlineCasherInfoResponse;
import cc.rengu.igas.share.core.model.MchntAuthInfo;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.model.MchntProdInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.enums.AcctTypeEnum;
import cc.rengu.oltp.service.common.enums.BaseProdEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.ConvertUtil;
import io.netty.util.internal.StringUtil;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * 收银台信息查询
 *
 * @author keyi
 * @modify by wangcheng
 * @date 2020/3/26.
 */
public class OnlineCasherInfoService extends ManageService {
    @Override
    protected Object bizBeforeCust() throws Exception {
        OnlineCasherInfoRequest onlineCasherInfoRequest = new OnlineCasherInfoRequest();
        ConvertUtil.convertOutput(onlineCasherInfoRequest);
        return onlineCasherInfoRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        BizResponse<OnlineCasherInfoResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        OnlineCasherInfoResponse onlineCasherInfoResponse = new OnlineCasherInfoResponse();

        OnlineCasherInfoRequest onlineCasherInfoRequest = (OnlineCasherInfoRequest) request;
        String instId = onlineCasherInfoRequest.getHeader().getInstId();
        String userOrderId = onlineCasherInfoRequest.getUserOrderId();

        //验证用户订单及商户订单信息
        OrderService orderService = new OrderServiceImpl();
        OrderInfo orderInfo = orderService.selectOrderInfoByUserOrderId(instId, userOrderId);
        if (null == orderInfo) {
            rglog.info("获取用户支付订单失败!");
            throw new BizException(RespCodeEnum.ORDER_NOEXIT.getRespCode(), RespCodeEnum.ORDER_NOEXIT.getRespDesc());
        }
        List<MchntOrderInfo> mchntOrderInfos = orderInfo.getMchntOrderInfoList();
        rglog.debug("商户订单个数:{}", mchntOrderInfos.size());

        //根据商户订单信息获取每个商户支持的产品信息
        List<MchntProdInfo> mchntPublicProdInfoList = new CopyOnWriteArrayList<>();
        MchntService mchntService = new MchntServiceImpl();
        for (MchntOrderInfo mchntOrderInfo : mchntOrderInfos) {
            //非独立维护资料的门店商户取连锁商户号获取商户支持的产品信息
            MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntOrderInfo.getMchntNo());
            if (null == mchntInfo) {
                rglog.error("获取商户基本信息失败:<{}>", mchntOrderInfo.getMchntNo());
                throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
            }
            String mchntNo = mchntOrderInfo.getMchntNo();
            if ("11".equals(mchntInfo.getMchntType()) && AppParamConstant.NO.equals(mchntInfo.getIndependentDataFlag())) {
                rglog.debug("商户:<{}>是非独立清算的门店商户，取所属的连锁商户号取获取支持的产品列表");
                mchntNo = mchntInfo.getChainMchntNo();
            }
            //获取商户支持的产品信息
            List<MchntProdInfo> mchntProdInfoList = mchntService.getMchntProdInfo(instId, mchntNo);
            if (null == mchntProdInfoList || mchntProdInfoList.isEmpty()) {
                rglog.info("商户无支持的产品列表");
                throw new BizException(RespCodeEnum.MCHNT_NO_PROD.getRespCode(), RespCodeEnum.MCHNT_NO_PROD.getRespDesc());
            }
            //取所有商户都支持的产品信息
            if (mchntPublicProdInfoList.isEmpty()) {
                mchntPublicProdInfoList.addAll(mchntProdInfoList);
            } else {
                for (MchntProdInfo mchntProdInfo : mchntPublicProdInfoList) {
                    Optional<MchntProdInfo> mchntProdInfoOpt = mchntProdInfoList.stream().filter(item -> item.getBaseProdCode().equals(mchntProdInfo.getBaseProdCode())).findFirst();
                    if (!mchntProdInfoOpt.isPresent()) {
                        mchntPublicProdInfoList.remove(mchntProdInfo);
                    }
                }
            }
            rglog.debug("当前所有商户都支持的产品个数:<{}>", mchntPublicProdInfoList.size());
        }

        if (mchntOrderInfos.size() > 1) {
            //合并支付订单不支持银联云闪付、分期支付
            mchntPublicProdInfoList = mchntPublicProdInfoList.stream().filter(item -> !item.getBaseProdCode().equals(BaseProdEnum.CUPS_CLOUD_PAY.getProdCode()) &&
                    !item.getBaseProdCode().equals(BaseProdEnum.STAGE_PAY.getProdCode())).collect(Collectors.toList());
            //获取平台商户是否支持微信app支付及小程序支付
            if (null == platMchntInfo || StringUtil.isNullOrEmpty(platMchntInfo.getWechatAppId())) {
                //若平台商户不支持微信APP支付及小程序支付，则收银台上也不展示微信支付的支付方式
                mchntPublicProdInfoList = mchntPublicProdInfoList.stream().filter(item -> !item.getBaseProdCode().equals(BaseProdEnum.WECHAT_PAY.getProdCode())).collect(Collectors.toList());
            }
        }

        //获商户的权限信息
        List<MchntAuthInfo> mchntAuthInfoList = mchntService.getMchntAuthInfo(instId, mchntOrderInfos.get(0).getMchntNo(), null);

        //转换输出的支付产品列表
        ArrayList<BizProdInfo> surportBizProdList = new ArrayList<>();
        for (MchntProdInfo mchntProdInfo : mchntPublicProdInfoList) {
            //按照业务产品代码过滤商户的交易权限
            List<MchntAuthInfo> mchntAuthInfos = mchntAuthInfoList.stream().filter(item -> item.getBaseProdCode().equals(mchntProdInfo.getBaseProdCode())).collect(Collectors.toList());
            //按照交易分组对商户权限进行分类
            Map<String, List<MchntAuthInfo>> mchntAuthInfoMap = mchntAuthInfos.stream().collect(Collectors.groupingBy(MchntAuthInfo::getTxnGroup));
            for (Map.Entry<String, List<MchntAuthInfo>> entry : mchntAuthInfoMap.entrySet()) {
                BizProdInfo bizProdInfo = new BizProdInfo();
                bizProdInfo.setBizProdCode(mchntProdInfo.getBaseProdCode());
                bizProdInfo.setTxnGroup(entry.getKey());
                surportBizProdList.add(bizProdInfo);
            }
        }
        onlineCasherInfoResponse.setSurportBizProdList(surportBizProdList);

        //获取收银台名称 logo-url/收银台名称
        if (platMchntInfo != null && !StringUtil.isNullOrEmpty(platMchntInfo.getLogoPath())) {
            onlineCasherInfoResponse.setCashierLogoUrl(platMchntInfo.getLogoPath());
            onlineCasherInfoResponse.setCashierName(platMchntInfo.getCashDeskName());
        } else {
            //通过系统参数表获取法人机构的 logo图片路径和银行名称
            SysParamService sysParamService = new SysParamServiceImpl();
            SysParam sysParamInfo = sysParamService.getSysParamInfo(instId, OpmsParamConstant.OPMS_SYS_PARAM, OpmsParamConstant.INST_INFO);
            if (null == sysParamInfo || AppParamConstant.NO.equals(sysParamInfo.getParamStatus())
                    || StringUtil.isNullOrEmpty(sysParamInfo.getParamValue())) {
                rglog.info("法人机构:<{}>未配置其银行信息-logoUrl和银行行名");
                throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
            }
            String[] split = sysParamInfo.getParamValue().split(",");
            if (split.length < 2) {
                rglog.warn("机构:<{}>配置的银行信息参数:<{}>不正确", instId, sysParamInfo.getParamValue());
                throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
            }
            onlineCasherInfoResponse.setCashierLogoUrl(split[0]);
            onlineCasherInfoResponse.setCashierName(split[1]);
        }

        onlineCasherInfoResponse.setMchntBelongInstId(platMchntInfo.getSignInstId());
        onlineCasherInfoResponse.setMchntName(platMchntInfo.getPlatMchntName());
        String authFlag = "1".equals(platMchntInfo.getGrantCreditFlag()) ? AppParamConstant.YES : AppParamConstant.NO;
        onlineCasherInfoResponse.setAuthFlag(authFlag);
        onlineCasherInfoResponse.setGatewayType(mchntGateWaySupportInfo(mchntOrderInfos, instId));
        bizResponse.setResult(onlineCasherInfoResponse);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        OnlineCasherInfoResponse onlineCasherInfoResponse = (OnlineCasherInfoResponse) bizResponse.getResult();
        ConvertUtil.convertInput(onlineCasherInfoResponse);
    }

    /**
     * 商户支持的网关支付列表
     *
     * @return 支持列表
     * @throws Exception 异常
     */
    private String mchntGateWaySupportInfo(List<MchntOrderInfo> mchntOrderInfos, String instId) throws Exception {
        StringBuilder gatePaySupport = new StringBuilder();
        Map<String, String> gateWayMap = new HashMap<>();
        MchntService mchntService = new MchntServiceImpl();
        for (MchntOrderInfo mchntOrderInfo : mchntOrderInfos) {
            //非独立维护资料的门店商户取连锁商户号获取商户支持的产品信息
            MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntOrderInfo.getMchntNo());
            if (null == mchntInfo) {
                rglog.error("查询商户基本信息失败<{}>", mchntOrderInfo.getMchntNo());
                throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
            }
            String realMchntNo = mchntInfo.getMchntNo();
            if ("11".equals(mchntInfo.getMchntType()) && AppParamConstant.NO.equals(mchntInfo.getIndependentDataFlag())) {
                rglog.debug("商户:<{}>是非独立清算的门店商户，取所属的连锁商户号取获取支持的产品列表");
                realMchntNo = mchntInfo.getChainMchntNo();
            }
            /*本行个人网关*/
            boolean checkResult = mchntService.checkMchntAuth(instId, realMchntNo, null, "P01PM007", "00", AcctTypeEnum.ALL.getAcctType());
            String supportFlag = checkResult ? OpmsParamConstant.OPMS_PARAM_YES : OpmsParamConstant.OPMS_PARAM_NO;
            if (gateWayMap.isEmpty() || !gateWayMap.containsKey("00")) {
                gateWayMap.put("00", supportFlag);
            } else if (!supportFlag.equals(gateWayMap.get("00"))) {
                gateWayMap.put("00", OpmsParamConstant.OPMS_PARAM_NO);
            }
            /*本行企业*/
            checkResult = mchntService.checkMchntAuth(instId, realMchntNo, null, "P01PM007", "01", AcctTypeEnum.ALL.getAcctType());
            supportFlag = checkResult ? OpmsParamConstant.OPMS_PARAM_YES : OpmsParamConstant.OPMS_PARAM_NO;
            if (gateWayMap.isEmpty() || !gateWayMap.containsKey("01")) {
                gateWayMap.put("01", supportFlag);
            } else if (!supportFlag.equals(gateWayMap.get("01"))) {
                gateWayMap.put("01", OpmsParamConstant.OPMS_PARAM_NO);
            }
            /*他行个人网关*/
            checkResult = mchntService.checkMchntAuth(instId, realMchntNo, null, "P01PM008", "00", AcctTypeEnum.ALL.getAcctType());
            supportFlag = checkResult ? OpmsParamConstant.OPMS_PARAM_YES : OpmsParamConstant.OPMS_PARAM_NO;
            if (gateWayMap.isEmpty() || !gateWayMap.containsKey("02")) {
                gateWayMap.put("02", supportFlag);
            } else if (!supportFlag.equals(gateWayMap.get("02"))) {
                gateWayMap.put("02", OpmsParamConstant.OPMS_PARAM_NO);
            }
            /*他行企业*/
            checkResult = mchntService.checkMchntAuth(instId, realMchntNo, null, "P01PM008", "01", AcctTypeEnum.ALL.getAcctType());
            supportFlag = checkResult ? OpmsParamConstant.OPMS_PARAM_YES : OpmsParamConstant.OPMS_PARAM_NO;
            if (gateWayMap.isEmpty() || !gateWayMap.containsKey("03")) {
                gateWayMap.put("03", supportFlag);
            } else if (!supportFlag.equals(gateWayMap.get("03"))) {
                gateWayMap.put("03", OpmsParamConstant.OPMS_PARAM_NO);
            }
            /*中金企业*/
            checkResult = mchntService.checkMchntAuth(instId, realMchntNo, null, "P01PM007", "04", AcctTypeEnum.ALL.getAcctType());
            supportFlag = checkResult ? OpmsParamConstant.OPMS_PARAM_YES : OpmsParamConstant.OPMS_PARAM_NO;
            if (gateWayMap.isEmpty() || !gateWayMap.containsKey("04")) {
                gateWayMap.put("04", supportFlag);
            } else if (!supportFlag.equals(gateWayMap.get("04"))) {
                gateWayMap.put("04", OpmsParamConstant.OPMS_PARAM_NO);
            }
        }
        /*按照KEY排序*/
        gateWayMap.entrySet().stream().sorted(Map.Entry.comparingByKey());
        /*转化成字符串*/
        for (String key : gateWayMap.keySet()) {
            gatePaySupport.append(gateWayMap.get(key));
        }
        return gatePaySupport.toString();
    }
}
